<template>
  <div class="nav-tabs" ref="tabScrollbarRef">
    <!-- 点击左侧菜单在顶部生成选项导航栏 -->
    <div
      class="ba-nav-tab"
      v-for="(item, idx) in navTabs.state.tabsView"
      @click="checkoutTab(item as any)"
      :class="navTabs.state.activeIndex == idx ? 'active' : ''"
      @contextmenu.prevent="onContextmenu(item as any, $event)"
      :key="idx"
      :ref="tabsRefs.set"
    >
      {{ item.meta.title }}
      <transition
        @after-leave="selectNavTab(tabsRefs[navTabs.state.activeIndex])"
        name="el-fade-in"
      >
        <!-- 删除标签的图标 -->
        <el-icon
          v-show="navTabs.state.tabsView.length > 1"
          class="close-icon"
          @click.stop="closeTab(item as any)"
        >
          <Close />
        </el-icon>
      </transition>
    </div>
    <div :style="activeBoxStyle" class="nav-tabs-active-box"></div>
  </div>
  <!-- 鼠标右键显示上下文的菜单 -->
  <Contextmenu
    ref="contextmenuRef"
    :items="state.contextmenuItems"
    @contextmenuItemClick="onContextmenuItem"
  />
</template>
<script lang="ts" setup>
import screenfull from "screenfull";
import { nextTick, onMounted, reactive, ref } from "vue";
import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router";
import type { RouteLocationNormalized } from "vue-router";
import { useConfig } from "@/store/config";
import { useNavTabs } from "@/store/navTabs"; //后台路由导航仓库
import { useTemplateRefsList } from "@vueuse/core";
import Contextmenu from "@/components/contectmenu/index.vue"; //鼠标右键显示上下文的菜单
import "animate.css"; //引入组件切换动画库
import horizontalScroll from "@/utils/horizontalScroll";
import useCurrentInstance from "@/utils/useCurrentInstance";
import { getFirstRoute, routePush } from "@/utils/router";

/**
 * 绑定for循环中的ref元素
 * v-for="i of 5" :key="i" :ref="refs.set"
 */
const tabsRefs = useTemplateRefsList<HTMLDivElement>(); //顶部导航栏的数组ref
const tabScrollbarRef = ref(); //nav-tabs的ref
const contextmenuRef = ref(); //右键点击tab打开的上下文菜单ref

const route = useRoute();
const router = useRouter();
const config = useConfig();
const navTabs = useNavTabs();
const { proxy } = useCurrentInstance();

interface ContextMenuItem {
  name: string;
  label: string;
  icon?: string;
  disabled?: boolean;
}

interface ContextmenuItemClickEmitArg extends ContextMenuItem {
  menu?: RouteLocationNormalized;
}

//右键点击tab弹出选项
const state: { contextmenuItems: ContextMenuItem[] } = reactive({
  contextmenuItems: [
    { name: "refresh", label: "重新加载", icon: "fa fa-refresh" },
    { name: "close", label: "关闭标签", icon: "fa fa-times" },
    { name: "fullScreen", label: "当前标签全屏", icon: "el-icon-FullScreen" },
    { name: "closeOther", label: "关闭其他标签", icon: "fa fa-minus" },
    { name: "closeAll", label: "关闭全部标签", icon: "fa fa-stop" },
  ],
});

const onContextmenuItem = async (item: ContextmenuItemClickEmitArg) => {
  const { name, menu } = item;
  if (!menu) return;
  switch (name) {
    case "refresh":
      //重新加载
      proxy.eventBus.emit("onTabViewRefresh", menu);
      break;
    case "close":
      //关闭标签
      closeTab(menu);
      break;
    case "closeOther":
      //关闭其他标签
      navTabs.closeTabs(menu);
      navTabs.setActiveRoute(menu);
      if (navTabs.state.activeRoute?.path !== route.path) {
        router.push(menu!.path);
      }
      break;
    case "closeAll":
      //关闭全部标签
      closeAllTab();
      break;
    case "fullScreen":
      //当前标签全屏
      if (route.path !== menu?.path) {
        router.push(menu?.path as string);
      }
      navTabs.setFullScreen(true);
      break;
  }
};

// 激活tab的样式
const activeBoxStyle = reactive({
  width: "0",
  transform: "translateX(0px)",
});

//点击顶部路由导航切换路由
const checkoutTab = (menu: RouteLocationNormalized) => {
  router.push({ path: menu.path, query: menu.query, params: menu.params });
};

// oncontextmenu 事件在元素中用户右击鼠标时触发并打开上下文菜单
//鼠标右击事件.prevent.阻止游览器默认事件
const onContextmenu = (menu: RouteLocationNormalized, el: MouseEvent) => {
  //非当前点击tab禁用刷新
  state.contextmenuItems[0].disabled = route.path !== menu.path;
  //当前只有一个tab时 禁用关闭其他和关闭全部
  state.contextmenuItems[3].disabled = state.contextmenuItems[4].disabled =
    navTabs.state.tabsView.length == 1 ? true : false;

  /**
   * onShowContextmenu事件为Contextmenu组件内部事件
   */
  const { clientX, clientY } = el;
  contextmenuRef.value.onShowContextmenu(menu, {
    x: clientX,
    y: clientY,
  });
};

// tab 激活状态切换 dom:v-for绑定的相应的ref元素
const selectNavTab = function (dom: HTMLDivElement) {
  if (!dom) {
    return false;
  }
  activeBoxStyle.width = dom.clientWidth + "px";
  activeBoxStyle.transform = `translateX(${dom.offsetLeft}px)`;

  let scrollLeft =
    dom.offsetLeft + dom?.clientWidth - tabScrollbarRef.value.clientWidth;
  if (dom.offsetLeft < tabScrollbarRef.value.scrollLeft) {
    tabScrollbarRef.value.scrollTo(dom.offsetLeft, 0);
  } else if (scrollLeft > tabScrollbarRef.value.scrollLeft) {
    tabScrollbarRef.value.scrollTo(scrollLeft, 0);
  }
};

//删除当前tab之后回到上一个tab
const toLastTab = () => {
  const lastTab = navTabs.state.tabsView.slice(-1)[0];
  if (lastTab) {
    router.push(lastTab.path);
  } else {
    router.push("/admin");
  }
};

// 关闭tab
const closeTab = (route: RouteLocationNormalized) => {
  navTabs.closeTab(route);
  proxy.eventBus.emit("onTabViewClose", route);
  if (navTabs.state.activeRoute?.path === route.path) {
    toLastTab();
  } else {
    navTabs.setActiveRoute(navTabs.state.activeRoute as any);
    nextTick(() => {
      selectNavTab(tabsRefs.value[navTabs.state.activeIndex]);
    });
  }

  contextmenuRef.value.onHideContextmenu();
};
// 关闭所有tab
// const closeAllTab = () => { };
const closeAllTab = () => {
  navTabs.closeTabs(false);
  let firstRoute = getFirstRoute(navTabs.state.tabsViewRoutes as any);
  if (firstRoute) routePush(firstRoute.path);
};

//顶部的面包屑导航路由数据更新
const updateTab = function (newRoute: RouteLocationNormalized) {
  // 每次登录默认添加第一个tab navTabs.state.tabsView
  navTabs.addTab(newRoute);
  // 激活当前tab
  navTabs.setActiveRoute(newRoute);

  //传入激活tab的index
  nextTick(() => {
    selectNavTab(tabsRefs.value[navTabs.state.activeIndex]);
    //tabsRefs v-for绑定的相应的ref元素
  });
};

//从loading页面到控制台页面 页面路由变化时更新顶部导航路由
onBeforeRouteUpdate(async (to) => {
  updateTab(to);
});

onMounted(() => {
  //获取当前路由数据 在loading之后跳转到菜单路由的第一个数据上
  updateTab(router.currentRoute.value);
  new horizontalScroll(tabScrollbarRef.value);
});
</script>
<style lang="scss" scoped>
// 顶部导航栏
.nav-tabs {
  overflow-x: auto;
  overflow-y: hidden;
  margin-right: var(--ba-main-space);
  scrollbar-width: none;
  //被选中的样式
  .active {
    background: v-bind(
      'config.layout.layoutMode == "Default" ? config.getColorVal("headerBarBackground"):"#f5f5f5"'
    );
  }

  &::-webkit-scrollbar {
    height: 5px;
  }

  &::-webkit-scrollbar-thumb {
    background: #eaeaea;
    border-radius: var(--el-border-radius-base);
    box-shadow: none;
    -webkit-box-shadow: none;
  }

  &::-webkit-scrollbar-track {
    background: v-bind(
      'config.layout.layoutMode == "Default" ? "none" : config.getColorVal("headerBarBackground")'
    );
  }

  &:hover {
    &::-webkit-scrollbar-thumb:hover {
      background: #c8c9cc;
    }
  }
}

.ba-nav-tab {
  white-space: nowrap;
  height: 40px;
}
</style>
